package com.example.utils;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import jakarta.annotation.Resource;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.TimeUnit;

/**
 * 作者:xuSen
 * 日期2025/4/29 16:09
 */

/**
 * CacheUtils类提供了缓存操作的工具方法，包括将对象和列表保存到缓存以及从缓存中获取它们
 * 使用Spring的@Component注解将其标记为Spring管理的组件，自动注入到Spring应用上下文中
 */
@Component
public class CacheUtils {

    /**
     * 自动注入StringRedisTemplate实例，用于操作Redis缓存中的字符串值
     */
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    /**
     * 从缓存中获取指定键的值，并将其转换为指定类型的对象
     * 如果缓存中没有对应的键，则返回null
     *
     * @param key      缓存键
     * @param itemType 需要转换的类型
     * @param <T>      泛型标记，表示任意类型
     * @return 转换后的对象，如果没有找到则返回null
     */
    public <T> T takeFromCache(String key, Class<T> itemType) {
        String s = stringRedisTemplate.opsForValue().get(key);
        if (s == null) return null;
        return JSONObject.parseObject(s).to(itemType);
    }

    /**
     * 从缓存中获取指定键的值，并将其转换为指定类型的列表
     * 如果缓存中没有对应的键，则返回null
     *
     * @param key      缓存键
     * @param itemType 列表中元素的类型
     * @param <T>      泛型标记，表示任意类型
     * @return 转换后的列表，如果没有找到则返回null
     */
    public <T> List<T> takeListFromCache(String key, Class<T> itemType) {
        String s = stringRedisTemplate.opsForValue().get(key);
        if (s == null) return null;
        return JSONArray.parseArray(s).toList(itemType);
    }

    /**
     * 将对象保存到缓存中，并设置缓存的过期时间
     *
     * @param key    缓存键
     * @param data   要保存的对象
     * @param expire 缓存过期时间（秒）
     * @param <T>    泛型标记，表示任意类型
     */
    public <T> void saveToCache(String key, T data, long expire) {
        stringRedisTemplate.opsForValue().set(key, JSONArray.from(data).toJSONString(), expire, TimeUnit.SECONDS);
    }

    /**
     * 将列表保存到缓存中，并设置缓存的过期时间
     *
     * @param key    缓存键
     * @param list   要保存的列表
     * @param expire 缓存过期时间（秒）
     * @param <T>    泛型标记，表示任意类型
     */
    public <T> void saveListToCache(String key, List<T> list, long expire) {
        stringRedisTemplate.opsForValue().set(key, JSONArray.from(list).toJSONString(), expire, TimeUnit.SECONDS);
    }
    public void deleteCachePattern(String key){
        Set<String> keys = Optional.ofNullable(stringRedisTemplate.keys(key)).orElse(Collections.emptySet());
        stringRedisTemplate.delete(keys);
    }
    public void deleteFromCache(String key) {
        stringRedisTemplate.delete(key);
    }
}

